package br.ufrj.dcc.compconc.modelo;


/**
 * Classe abstrata que representa o modelo de programador para a aplicacao.
 * Ela implementa a interface <code>Runnable</code> para que suas classes derivadas sejam caracterizadas como threads.
 * @author Joao Paulo de Freitas Ramirez e Joao Lucas Nery
 *
 */
public abstract class Programador implements Runnable{
	/**
	 * ID da thread
	 */
	protected int id;
	
	/**
	 * Tipo de programador: Java ou C
	 */
	protected String tipo;
	
	/**
	 * Barco onde o programador usa para embarcar
	 */
	protected Barco barco;
	
	/**
	 * Um estado para a situacao de embarcado ou nao embarcado
	 */
	protected boolean embarcado;
	
	
	/**
	 * Construtor com a funcao de inicializar as variaveis de instancia comum a todos os tipos de programadores
	 * @param id A ID da Thread
	 * @param barco Barco que o programador usa para embarcar
	 */
	protected Programador(int id, Barco barco){
		this.id = id;
		this.barco = barco;
		this.embarcado = false;
	}
	
	/**
	 * Obtem o tipo do programador
	 * @return uma <code>String</code> especificando o tipo de programador
	 */
	public String getTipo(){
		return this.tipo;
	}
	
	/**
	 * Obtem a ID da Thread programador
	 * @return um <code>int</code> especificando a ID da Thread
	 */ 
	public int getId(){
		return this.id;
	}

	/**
	 * Obtem o estado dizendo se o programador esta ou nao embarcado
	 * @return um <code>boolean</code> indicando se o programador esta embarcado
	 */
	public boolean estaEmbarcado(){
		return this.embarcado;
	}
	
	/**
	 * Muda o estado atual do programador se nao estava embarcado, usando esse metodo passara a ficar embarcado e vice-versa
	 */
	public void mudaEstadoEmbarcado(){
		this.embarcado = !this.embarcado;
	}
	
	/**
	 * Sobre-escrita do metodo run() de <code>Runnable</code>.
	 * O programador tenta entrar no barco ate que esteja embarcado ou que alguma condicao gerada pelo barco force o programador
	 * a para suas tentativas.
	 * @see Programador#estaEmbarcado()
	 * @see Barco#board(Programador)
	 */
	@Override
	public void run(){
		while(!this.estaEmbarcado()){
			try{
				if(!this.barco.board(this)) break;
				this.sleep(this.id*100);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * Faz com que a Thread atual cesse suas atividades por algum periodo
	 * @param k periodo de cessamento da atividade da Thread
	 */
	public void sleep(int k){
		for(int j=0; j<k; k++){
			
		}
	}
	
}
